package thread.pool.exception;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 自己扩展并封装一个线程池，处理任务执行异常
 */
public class TraceThreadPoolExecutor extends ThreadPoolExecutor {
    public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                   TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable task) {
        super.execute(wrap(task, clientTrace()));
    }

    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(wrap(task, clientTrace()));
    }

    /**
     * 自定义一个线程执行异常
     * @return
     */
    private Exception clientTrace() {
        return new Exception("Client stack trace");
    }

    /**
     * 替换原任务，给原任务封装一层，对异常进行捕获
     * @param task
     * @param clientStack
     * @return
     */
    private Runnable wrap(final Runnable task, final Exception clientStack) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    task.run();
                } catch (Exception e) {
                    clientStack.printStackTrace();
                    throw e;
                }

            }
        };
    }
}
